﻿///<reference path="_references.ts" />
///<reference path="GameStateProvider.ts" />
///<reference path="Cooldowns.ts" />
///<reference path="Utility/_all.ts" />
///<reference path="Modules/IModule.ts" />
///<reference path="Modules/Birth.ts" />
///<reference path="Modules/Meta.ts" />
///<reference path="Modules/Message.ts" />
///<reference path="Modules/FirstMoves.ts" />
///<reference path="Modules/StatusDisplay.ts" />
///<reference path="Modules/Play.ts" />
///<reference path="Modules/Inventory.ts" />
///<reference path="Modules/BabyFinale.ts" />
///<reference path="Modules/YoungAdult.ts" />
///<reference path="Modules/HatEvent.ts" />
///<reference path="Modules/Job.ts" />
///<reference path="Modules/EndGame.ts" />
///<reference path="Modules/Empty.ts" />

module ScrambledEggs {
    export class Game {
        public GameState: GameStateProvider;
        private _modules: Modules.IModule[] = [];
        private _empty: Modules.IModule = new Modules.Empty();

        constructor() {
            var key = Utility.QueryString.Find("key");
            if (key == null)
                key = Utility.Key.generate();

            this.GameState = new GameStateProvider(key);
        }

        run(): void {
            var me = this;
            var ready = false;

            me.GameState.load(function () {
                Cooldowns.AutoResolve(me.GameState);
                if (ready)
                    me.onUpdate(me._empty);
                else ready = true;
            });

            me.fetchModules();
            me.initializeModules();

            if (ready)
                me.onUpdate(me._empty);
            else ready = true;

            (<any>window).withGame = function (callback) {
                callback(me, me.GameState.State);
                me.onUpdate(me._empty);
            }
        }

        fetchModules(): void {
            this._modules.push(new Modules.Birth());
            this._modules.push(new Modules.Meta());
            this._modules.push(new Modules.Message());
            this._modules.push(new Modules.FirstMoves());
            this._modules.push(new Modules.Play());
            this._modules.push(new Modules.Inventory());
            this._modules.push(new Modules.BabyFinale());
            this._modules.push(new Modules.YoungAdult());
            this._modules.push(new Modules.HatEvent());
            this._modules.push(new Modules.Job());
            this._modules.push(new Modules.EndGame());
            this._modules.push(new Modules.StatusDisplay()); // get rendered last
        }

        initializeModules(): void {
            var me = this;
            $.each(this._modules, function (i: number, mod: Modules.IModule) {
                mod.initialize(me.GameState, function () { me.onUpdate(mod); } );
            });
        }

        onUpdate(source: Modules.IModule): void {
            var me = this;
            $.each(me._modules, function () {
                var m = this;
                m.update(me.GameState, source);
            });
        }
    }

    $(document).ready(function () {
        var game = new Game();
        game.run();

        $(".noselect").on("selectstart", function (event: JQueryEventObject) {
            event.preventDefault();
            event.stopPropagation();
            return false;
        });
    });
}